package cn.zhangzhan.common.core.utils.bean;

import cn.hutool.core.bean.BeanException;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 张一恒
 * @version 1.0
 * @description: 类对象/集合拷贝 深拷贝
 * @date 2023/1/30 22:40
 */
@Slf4j
public class DoCopyUtils {

    /**
     * 类对象拷贝
     */
    @SuppressWarnings("unchecked")
    public static <T> T copyBean(Object o, Class<T> clazz) {
//        将源对象赋值到目标对象方法：
//        方法一：BeanUtils.copyProperties(源对象, 目标对象); //cn.hutool.core.bean.BeanUtil;
//        方法二：目标对象 = JSONObject.parseObject(JSON.toJSONString(源对象), 目标对象.class); //com.alibaba.fastjson.JSON; com.alibaba.fastjson.JSONObject;
//
//        实测结果方法一的耗时为方法二的2-3倍。
        T res = null;
        try {
            res = clazz.newInstance();
            res = (T) JSON.parseObject(JSON.toJSONString(o, SerializerFeature.WriteNullStringAsEmpty), res.getClass());
        } catch (ClassCastException e) {
            res = BeanUtil.copyProperties(o, clazz);
        } catch (IllegalAccessException | InstantiationException e) {
            log.error("对象创建异常", e);
            throw new BeanException("对象创建异常", e.getMessage());
        }
        return res;
    }


    /**
     * 集合对象拷贝
     */
    public static <T, O> List<T> copyToList(List<O> os, Class<T> clazz) {
        //利用反射创建对象
        return os.stream().map(po -> copyBean(po, clazz)).collect(Collectors.toList());
    }

    /**
     * 集合对象拷贝(返回不可变集合)
     */
    public static <T, O> List<T> copyToImmutableList(List<O> os, Class<T> clazz) {
        //利用反射创建对象
        return ImmutableList.copyOf(os.stream().map(po -> copyBean(po, clazz)).collect(Collectors.toList()));
    }


}
